package com.question.common.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.question.business.auth.model.dto.UserDetailDTO;
import com.question.common.constants.NumberConstants;
import com.question.common.constants.RedisConstants;
import com.question.common.constants.SecurityConstants;
import com.question.common.constants.StringConstants;
import com.question.common.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 当前用户
 *
 * @author star
 * @since 2021-01-18
 */
@Slf4j
@Component
@AllArgsConstructor
public class CurrentUserUtil {

    private final RedisTemplate redisTemplate;
    private final HttpServletRequest request;
    private static final String EXPORT = "/export";

    /**
     * 设置用户信息
     *
     * @param token      token
     * @param userDetail 用户信息
     */
    public void setUser(String token, UserDetailDTO userDetail) {
        ValueOperations<String, UserDetailDTO> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(RedisConstants.AUTH_TOKEN.concat(token), userDetail, NumberConstants.ONE_LONG, TimeUnit.HOURS);
    }

    /**
     * 退出登录
     */
    public void logOut() {
        redisTemplate.delete(RedisConstants.AUTH_TOKEN.concat(this.getToken()));
    }


    /**
     * 获取用户信息
     *
     * @return UserDetailDTO
     */
    public UserDetailDTO getUser() {
        return getUser(this.getToken());
    }

    /**
     * 获取用户信息
     *
     * @param token token
     * @return UserDetailDTO
     */
    public UserDetailDTO getUser(String token) {
        ValueOperations<String, UserDetailDTO> valueOperations = redisTemplate.opsForValue();
        UserDetailDTO userDetail = valueOperations.get(RedisConstants.AUTH_TOKEN.concat(token));
        if (Objects.isNull(userDetail) || StringUtils.isBlank(userDetail.getId())) {
            log.error("认证失败：token不存在");
            throw new BusinessException("认证失败：token不存在");
        }
        return userDetail;
    }

    /**
     * 获取token
     *
     * @return String
     */
    public String getToken() {
        if (Objects.nonNull(request)) {
            String token = getToken(request);
            if (StringUtils.isNotBlank(token)) {
                return token;
            }
            log.error("认证失败：token为空");
            throw new BusinessException("认证失败：token为空");
        } else {
            log.error("获取token但是HttpServletRequest为空");
            throw new BusinessException("获取token但是HttpServletRequest为空");
        }
    }

    /**
     * 获取token
     *
     * @return String
     */
    public String getToken(@NotNull HttpServletRequest request) {
        String path = request.getRequestURI();
        String authorization = request.getHeader(SecurityConstants.AUTHORIZATION);
        String token = null;

        if (StringUtils.isNotBlank(authorization) && authorization.length() > NumberConstants.SEVEN) {
            token = authorization.substring(NumberConstants.SEVEN);
        }

        if (StringUtils.isNotBlank(token)) {
            return token;
        } else {
            if (StringUtils.isNotBlank(path) && path.replace(StringConstants.DOUBLE_SLASH, StringConstants.SLASH).endsWith(EXPORT)) {
                return request.getParameter(SecurityConstants.TOKEN_HEADER);
            }
        }
        return null;
    }

}
